package com.xjrsoft.common.utils;

import cn.hutool.core.util.PageUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.db.DbUtil;
import cn.hutool.db.Page;
import cn.hutool.db.ds.simple.SimpleDataSource;
import cn.hutool.db.meta.MetaUtil;
import cn.hutool.extra.spring.SpringUtil;
import com.baomidou.dynamic.datasource.DynamicRoutingDataSource;
import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DataSourceProperty;
import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DynamicDataSourceProperties;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.toolkit.JdbcUtils;
import com.xjrsoft.common.constant.GlobalConstant;
import com.xjrsoft.common.enums.*;
import com.xjrsoft.module.generator.entity.TableFieldConfig;
import com.xjrsoft.module.generator.entity.TableStructureConfig;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ArrayUtils;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * @title: 数据源工具类
 * @Author tzx
 * @Date: 2022/4/17 14:55
 * @Version 1.0
 */
@Slf4j
public class DatasourceUtil {


    /**
     * 获取主数据源
     *
     * @return
     */
    public static DataSource getDatasourceMaster() {
        DynamicRoutingDataSource dynamicRoutingDataSource = SpringUtil.getBean(DynamicRoutingDataSource.class);
        return dynamicRoutingDataSource.getDataSource(GlobalConstant.DEFAULT_DATASOURCE_KEY);
    }

    /**
     * 获取数据源
     *
     * @return
     */
    public static DataSource getDataSource(String id) {
        DynamicRoutingDataSource dynamicRoutingDataSource = SpringUtil.getBean(DynamicRoutingDataSource.class);
        try {
            return dynamicRoutingDataSource.getDataSource(id);
        } catch (Exception e) {
            throw new RuntimeException("获取数据源失败： " + id);
        }
    }

    public static DbType getDataSourceMasterDbType() {
        DynamicDataSourceProperties dynamicDataSourceProperties = SpringUtil.getBean(DynamicDataSourceProperties.class);
        DataSourceProperty datasource = dynamicDataSourceProperties.getDatasource().get(dynamicDataSourceProperties.getPrimary());
        return JdbcUtils.getDbType(datasource.getUrl());
    }



    /**
     * 关闭链接
     *
     * @return
     */
    @SneakyThrows
    public static void close(Connection connection, ResultSet resultSet) {
        if (resultSet != null) {
            resultSet.close();
        }
        if (connection != null) {
            connection.close();
        }
    }

    /**
     * 构建分页查询sql
     *
     * @param sql
     * @param page
     * @return
     */
    public static String wrapperPageSql(String sql, Page page, DbType dbType) {
        switch (dbType) {
            case MYSQL:
                return wrapperPageSqlForMysql(sql, page);
            case ORACLE:
            case ORACLE_12C:
                return wrapperPageSqlForOracle(sql, page);
            case SQL_SERVER:
            case SQL_SERVER2005:
                return wrapperPageSqlForSqlServer(sql, page);
            case POSTGRE_SQL:
                return wrapperPageSqlForPostgreSql(sql, page);
            case DM:
                return wrapperPageSqlForDm(sql, page);
            case DB2:
                return wrapperPageSqlForDb2(sql, page);
            case KINGBASE_ES:
                return wrapperPageSqlForKingBaseEs(sql, page);
            case GAUSS:
                return wrapperPageSqlForGauss(sql, page);
            default:
                return sql;
        }
    }

    private static String wrapperPageSqlForMysql(String sql, Page page) {
        return "select * from (" + sql + ") t" + " limit " + PageUtil.getStart(page.getPageNumber(), page.getPageSize()) + "," +page.getPageSize();
    }

    private static String wrapperPageSqlForOracle(String sql, Page page) {
        return "select * from ( SELECT row_.*, rownum rownum_ from ( " + sql + " ) row_ where rownum <= " + PageUtil.getStart(page.getPageNumber(), page.getPageSize()) + ") table_alias where table_alias.rownum_ >" + PageUtil.getEnd(page.getPageNumber(), page.getPageSize());
    }

    private static String wrapperPageSqlForSqlServer(String sql, Page page) {
        return "select * FROM ( " + sql + " ) t ORDER BY current_timestamp offset " + PageUtil.getStart(page.getPageNumber(), page.getPageSize()) + " rows fetch next " + PageUtil.getEnd(page.getPageNumber(), page.getPageSize()) + " rows only";
    }

    private static String wrapperPageSqlForPostgreSql(String sql, Page page) {
        return "select * FROM ( " + sql + " ) t limit " + page.getPageNumber() + " offset " + page.getPageSize();
    }

    private static String wrapperPageSqlForDm(String sql, Page page) {
        return "select * from (" + sql + ") t" + " limit " + PageUtil.getStart(page.getPageNumber(), page.getPageSize()) + "," + PageUtil.getEnd(page.getPageNumber(), page.getPageSize());
    }

    private static String wrapperPageSqlForDb2(String sql, Page page) {
        return "select row_num() over() as rownum,* from ( " + sql + " ) where rownum > " + PageUtil.getStart(page.getPageNumber(), page.getPageSize()) + " and rownum < " + PageUtil.getEnd(page.getPageNumber(), page.getPageSize());
    }

    private static String wrapperPageSqlForKingBaseEs(String sql, Page page) {
        return "select * FROM ( " + sql + " ) t limit " + page.getPageNumber() + " offset " + page.getPageSize();
    }

    private static String wrapperPageSqlForGauss(String sql, Page page) {
        return "select * FROM ( " + sql + " ) t limit " + page.getPageNumber() + " offset " + page.getPageSize();
    }

    private static String wrapperPageCount(String sql, Page page) {
        return "select count(*) from (" + sql + ") t";
    }

    /**
     * 构建测试sql
     *
     * @return
     */
    public static String wrapperTestSql(DbType dbType) {
        switch (dbType) {
            case ORACLE:
            case ORACLE_12C:
                return "SELECT 1 FROM DUAL";
            default:
                return "select 1";
        }
    }

    /**
     * 构建测试sql
     *
     * @return
     */
    public static String wrapperDropSql(String tableName) {
        return "drop table " + tableName;
    }


    /**
     * 构建建表sql语句
     *
     * @param tableStructureConfigs
     * @return
     */
    public static List<String> wrapperCreateTableSql(List<TableStructureConfig> tableStructureConfigs, DbType dbType, String databaseId) {
        switch (dbType) {
            case ORACLE:
            case ORACLE_12C:
            case DM:
                return wrapperCreateTableSqlForOracle(tableStructureConfigs, dbType);
            case DB2:
                return wrapperCreateTableSqlForDB2(tableStructureConfigs);
            case SQL_SERVER2005:
            case SQL_SERVER:
                return wrapperCreateTableSqlForSqlServer(tableStructureConfigs);
            case POSTGRE_SQL:
            case KINGBASE_ES:
            case GAUSS:
                return wrapperCreateTableSqlForPostgreSql(tableStructureConfigs);
            default:
                return wrapperCreateTableSqlForMysql(tableStructureConfigs, databaseId);
        }
    }

    private static List<String> wrapperCreateTableSqlForMysql(List<TableStructureConfig> tableStructureConfigs, String databaseId) {
        List<String> sqls = new ArrayList<>();
        //遍历所有表配置
        for (TableStructureConfig tableStructureConfig : tableStructureConfigs) {
            String tableName = tableStructureConfig.getTableName();
            // 创建新表和覆盖旧表才需要创建表
            Integer operator = tableStructureConfig.getOperator();
            if (operator == 1) {
                continue;
            }
            StringBuilder sb = new StringBuilder();
            String[] oldFields = null;
            if (operator == 3) {
//                sqls.add(wrapperDropSql(tableStructureConfig.getTableName()));
                oldFields = MetaUtil.getColumnNames(DatasourceUtil.getDataSource(databaseId), tableName);
            } else {

                sb.append("CREATE TABLE `").append(tableName).append("` ( \n");
                sb.append("  `").append(GlobalConstant.DEFAULT_PK).append("` bigint NOT NULL, \n");
            }

            List<TableFieldConfig> tableFieldConfigs = tableStructureConfig.getTableFieldConfigs();

            //遍历当前表配置的 字段配置
            for (TableFieldConfig tableFieldConfig : tableFieldConfigs) {
                MySqlFieldsType fieldType = MySqlFieldsType.getFieldType(tableFieldConfig.getFieldType());
                String type = fieldType.getType();
                StringBuilder fieldSql = new StringBuilder();
                switch (fieldType) {
                    //普通文本
                    case VARCHAR:
                        fieldSql.append(tableFieldConfig.getFieldName()).append(" ").append(type).append("(").append(tableFieldConfig.getFieldLength()).append(") COMMENT '" + tableFieldConfig.getFieldComment() + "'");
                        break;
                    //长文本
                    case VARCHARMAX:
                    //数字
                    case INT:
                    case FLOAT:
                    //日期
                    case DATE:
                    //日期时间
                    case DATETIME:
                    //长数字
                    case FK:
                    case LONG:
                    //长数字
                    case TIME:
                        fieldSql.append("    `").append(tableFieldConfig.getFieldName()).append("` ").append(type).append(" COMMENT '").append(tableFieldConfig.getFieldComment()).append("'");
                        break;
                    default:
                        fieldSql.append("    `").append(tableFieldConfig.getFieldName()).append("` ").append(type).append("(").append(GlobalConstant.DEFAULT_TEXT_LENGTH).append(") COMMENT '").append(tableFieldConfig.getFieldComment()).append("'");
                        break;
                }
                if (operator == 3 && ArrayUtils.isNotEmpty(oldFields) && Arrays.stream(oldFields).noneMatch(field -> StrUtil.equalsIgnoreCase(field, tableFieldConfig.getFieldName()))) {
                    sqls.add("ALTER TABLE " + tableName + " ADD " + fieldSql.toString());
                } else {
                    fieldSql.append(",  \n");
                    sb.append(fieldSql);
                }

            }

            if (operator != 3) {
                //如果不是主表 默认需要新增主表关联字段 用于关联主表  默认字段名为 parent + _id
                if(!tableStructureConfig.getIsMain()){
                    sb.append("  `").append(GlobalConstant.DEFAULT_FK).append("` bigint , \n");
                }

                sb.append("  PRIMARY KEY (`").append(GlobalConstant.DEFAULT_PK).append("`) \n");
                sb.append(") ENGINE=`InnoDB` DEFAULT CHARACTER SET utf8mb4 COMMENT='").append(tableStructureConfig.getTableComment()).append("';\n");

                sqls.add(sb.toString());
            }
        }
        return sqls;
    }

    private static List<String> wrapperCreateTableSqlForOracle(List<TableStructureConfig> tableStructureConfigs, DbType dbType) {
        List<String> sqls = new ArrayList<>();
        //遍历所有表配置
        for (TableStructureConfig tableStructureConfig : tableStructureConfigs) {
            // 创建新表和覆盖旧表才需要创建表
            Integer operator = tableStructureConfig.getOperator();
            if (operator == 1) {
                continue;
            }
            if (operator == 3) {
                sqls.add(wrapperDropSql(tableStructureConfig.getTableName()));
            }
            StringBuilder sb = new StringBuilder();
            sb.append("CREATE TABLE ").append(tableStructureConfig.getTableName()).append(" ( \n");
            sb.append("  ").append(GlobalConstant.DEFAULT_PK).append(" NUMBER(20, 0) NOT NULL, \n");

            List<TableFieldConfig> tableFieldConfigs = tableStructureConfig.getTableFieldConfigs();

            //遍历当前表配置的 字段配置
            for (TableFieldConfig tableFieldConfig : tableFieldConfigs) {
                OracleFieldsType fieldType = OracleFieldsType.getFieldType(tableFieldConfig.getFieldType());
                String type = fieldType.getType();
                switch (fieldType) {
                    //普通文本
                    case VARCHAR:
                        sb.append(tableFieldConfig.getFieldName()).append(" ").append(type).append("(").append(tableFieldConfig.getFieldLength()).append("),  \n");
                        break;
                    //数字
                    case INT:
                        sb.append(tableFieldConfig.getFieldName()).append(" ").append(type).append("(11, 0),  \n");
                        break;
                    //长数字
                    case FK:
                    case LONG:
                        sb.append(tableFieldConfig.getFieldName()).append(" ").append(type).append("(20, 0),  \n");
                        break;
                    //小数
                    case FLOAT:
                        sb.append(tableFieldConfig.getFieldName()).append(" ").append(type).append("(20, 10),  \n");
                        break;
                    //长文本
                    case VARCHARMAX:
                        sb.append(tableFieldConfig.getFieldName()).append(" ").append(type).append("(2000),  \n");
                        break;
                    //日期
                    case DATE:
                    case DATETIME:
                    // 时间
                    case TIME:
                        if (dbType == DbType.DM && fieldType == OracleFieldsType.TIME) {
                            sb.append(tableFieldConfig.getFieldName()).append(" ").append("TIME").append(",  \n");
                        } else {
                            sb.append(tableFieldConfig.getFieldName()).append(" ").append(type).append(",  \n");
                        }
                        break;
                    default:
                        sb.append(tableFieldConfig.getFieldName()).append(" ").append(type).append("(").append(GlobalConstant.DEFAULT_TEXT_LENGTH).append("),  \n");
                        break;
                }

            }
            //如果不是主表 默认需要新增主表关联字段 用于关联主表  默认字段名为 parent + _id
            if(!tableStructureConfig.getIsMain()){
                sb.append("  ").append(GlobalConstant.DEFAULT_FK).append(" NUMBER(20, 0), \n");
            }


            sb.append("  PRIMARY KEY (").append(GlobalConstant.DEFAULT_PK).append(") \n");
            sb.append(") \n");

            sqls.add(sb.toString());
        }
        for (TableStructureConfig tableStructureConfig : tableStructureConfigs) {
            List<TableFieldConfig> tableFieldConfigs = tableStructureConfig.getTableFieldConfigs();
            //遍历当前表配置的 字段配置
            for (TableFieldConfig tableFieldConfig : tableFieldConfigs) {
                sqls.add("COMMENT ON COLUMN " + tableStructureConfig.getTableName() + "." + tableFieldConfig.getFieldName() + " IS '" + tableFieldConfig.getFieldComment() + "'");
            }

        }
        return sqls;
    }

    private static List<String> wrapperCreateTableSqlForDB2(List<TableStructureConfig> tableStructureConfigs) {
        List<String> sqls = new ArrayList<>();
        //遍历所有表配置
        for (TableStructureConfig tableStructureConfig : tableStructureConfigs) {
            // 创建新表和覆盖旧表才需要创建表
            Integer operator = tableStructureConfig.getOperator();
            if (operator == 1) {
                continue;
            }
            if (operator == 3) {
                sqls.add(wrapperDropSql(tableStructureConfig.getTableName()));
            }
            StringBuilder sb = new StringBuilder();
            sb.append("CREATE TABLE ").append(tableStructureConfig.getTableName()).append(" ( \n");
            sb.append("  ").append(GlobalConstant.DEFAULT_PK).append(" BIGINT NOT NULL, \n");

            List<TableFieldConfig> tableFieldConfigs = tableStructureConfig.getTableFieldConfigs();

            //遍历当前表配置的 字段配置
            for (TableFieldConfig tableFieldConfig : tableFieldConfigs) {
                DB2FieldsType fieldType = DB2FieldsType.getFieldType(tableFieldConfig.getFieldType());
                String type = fieldType.getType();
                switch (fieldType) {
                    //普通文本
                    case VARCHAR:
                        sb.append(tableFieldConfig.getFieldName()).append(" ").append(type).append("(").append(tableFieldConfig.getFieldLength()).append("),  \n");
                        break;
                    //数字
                    case INT:
                    //长数字
                    case FK:
                    case LONG:
                    //小数
                    case FLOAT:
                    //长文本
                    case VARCHARMAX:
                    //日期
                    case DATE:
                    case DATETIME:
                        // 时间
                    case TIME:
                        sb.append(tableFieldConfig.getFieldName()).append(" ").append(type).append(",  \n");
                        break;
                    default:
                        sb.append(tableFieldConfig.getFieldName()).append(" ").append(type).append("(").append(GlobalConstant.DEFAULT_TEXT_LENGTH).append("),  \n");
                        break;
                }

            }
            //如果不是主表 默认需要新增主表关联字段 用于关联主表  默认字段名为 parent + _id
            if(!tableStructureConfig.getIsMain()){
                sb.append("  ").append(GlobalConstant.DEFAULT_FK).append(" BIGINT, \n");
            }


            sb.append("  PRIMARY KEY (").append(GlobalConstant.DEFAULT_PK).append(") \n");
            sb.append(") \n");

            sqls.add(sb.toString());
        }
        for (TableStructureConfig tableStructureConfig : tableStructureConfigs) {
            Integer operator = tableStructureConfig.getOperator();
            if (operator == 1) {
                continue;
            }
            List<TableFieldConfig> tableFieldConfigs = tableStructureConfig.getTableFieldConfigs();
            //遍历当前表配置的 字段配置
            for (TableFieldConfig tableFieldConfig : tableFieldConfigs) {
                sqls.add("COMMENT ON COLUMN " + tableStructureConfig.getTableName() + "." + tableFieldConfig.getFieldName() + " IS '" + tableFieldConfig.getFieldComment() + "'");
            }

        }
        return sqls;
    }

    private static List<String> wrapperCreateTableSqlForSqlServer(List<TableStructureConfig> tableStructureConfigs) {
        List<String> sqls = new ArrayList<>();
        //遍历所有表配置
        for (TableStructureConfig tableStructureConfig : tableStructureConfigs) {
            // 创建新表和覆盖旧表才需要创建表
            Integer operator = tableStructureConfig.getOperator();
            if (operator == 1) {
                continue;
            }
            if (operator == 3) {
                sqls.add(wrapperDropSql(tableStructureConfig.getTableName()));
            }

            StringBuilder sb = new StringBuilder();
            sb.append("CREATE TABLE ").append(tableStructureConfig.getTableName()).append(" ( \n");
            sb.append("  ").append(GlobalConstant.DEFAULT_PK).append(" bigint NOT NULL, \n");

            List<TableFieldConfig> tableFieldConfigs = tableStructureConfig.getTableFieldConfigs();

            //遍历当前表配置的 字段配置
            for (TableFieldConfig tableFieldConfig : tableFieldConfigs) {
                SqlServerFieldsType fieldType = SqlServerFieldsType.getFieldType(tableFieldConfig.getFieldType());
                String type = fieldType.getType();
                switch (fieldType) {
                    //普通文本
                    case VARCHAR:
                        sb.append(tableFieldConfig.getFieldName()).append(" ").append(type).append("(").append(tableFieldConfig.getFieldLength()).append("),  \n");
                        break;
                    //长文本
                    case VARCHARMAX:
                        sb.append(tableFieldConfig.getFieldName()).append(" ").append(type).append("(max),  \n");
                        break;
                    //数字
                    case INT:
                    //小数
                    case FLOAT:
                    //日期
                    case DATE:
                    case DATETIME:
                    //长数字
                    case FK:
                    case LONG:
                    // 时间
                    case TIME:
                        sb.append(tableFieldConfig.getFieldName()).append(" ").append(type).append(",  \n");
                        break;
                    default:
                        sb.append(tableFieldConfig.getFieldName()).append(" ").append(type).append("(").append(GlobalConstant.DEFAULT_TEXT_LENGTH).append("),  \n");
                        break;
                }

            }

            //如果不是主表 默认需要新增主表关联字段 用于关联主表  默认字段名为 parent + _id
            if(!tableStructureConfig.getIsMain()){
                sb.append("  ").append(GlobalConstant.DEFAULT_FK).append(" bigint , \n");
            }

            sb.append("  PRIMARY KEY (").append(GlobalConstant.DEFAULT_PK).append(") \n");
            sb.append("); \n");

            sqls.add(sb.toString());
        }
        for (TableStructureConfig tableStructureConfig : tableStructureConfigs) {
            List<TableFieldConfig> tableFieldConfigs = tableStructureConfig.getTableFieldConfigs();
            //遍历当前表配置的 字段配置
            for (TableFieldConfig tableFieldConfig : tableFieldConfigs) {//给sqlserver数据库的数据设值备注信息
                sqls.add("EXEC sys.sp_addextendedproperty 'MS_Description', N'"+tableFieldConfig.getFieldComment()+"', 'schema', N'dbo', 'table', N'"+tableStructureConfig.getTableName()+"', 'column', N'"+tableFieldConfig.getFieldName()+"';");
            }
        }
        return sqls;
    }

    private static List<String> wrapperCreateTableSqlForPostgreSql(List<TableStructureConfig> tableStructureConfigs) {
        List<String> sqls = new ArrayList<>();
        //遍历所有表配置
        for (TableStructureConfig tableStructureConfig : tableStructureConfigs) {
            // 创建新表和覆盖旧表才需要创建表
            Integer operator = tableStructureConfig.getOperator();
            if (operator == 1) {
                continue;
            }
            if (operator == 3) {
                sqls.add(wrapperDropSql(tableStructureConfig.getTableName()));
            }
            StringBuilder sb = new StringBuilder();
            sb.append("CREATE TABLE ").append(tableStructureConfig.getTableName()).append(" ( \n");
            sb.append("  ").append(GlobalConstant.DEFAULT_PK).append(" bigint NOT NULL, \n");

            List<TableFieldConfig> tableFieldConfigs = tableStructureConfig.getTableFieldConfigs();

            //遍历当前表配置的 字段配置
            for (TableFieldConfig tableFieldConfig : tableFieldConfigs) {
                PostgreSqlFieldsType fieldType = PostgreSqlFieldsType.getFieldType(tableFieldConfig.getFieldType());
                String type = fieldType.getType();
                switch (fieldType) {
                    //普通文本
                    case VARCHAR:
                        sb.append(tableFieldConfig.getFieldName()).append(" ").append(type).append("(").append(tableFieldConfig.getFieldLength()).append("),  \n");
                        break;
                    //长文本
                    case VARCHARMAX:
                    //数字
                    case INT:
                    //长数字
                    case FK:
                    case LONG:
                    //小数
                    case FLOAT:
                    //日期
                    case DATE:
                    case DATETIME:
                    case TIME:
                        sb.append(tableFieldConfig.getFieldName()).append(" ").append(type).append(",  \n");
                        break;
                    default:
                        sb.append(tableFieldConfig.getFieldName()).append(" ").append(type).append("(").append(GlobalConstant.DEFAULT_TEXT_LENGTH).append("),  \n");
                        break;
                }

            }
            //如果不是主表 默认需要新增主表关联字段 用于关联主表  默认字段名为 parent + _id
            if(!tableStructureConfig.getIsMain()){
                sb.append("  ").append(GlobalConstant.DEFAULT_FK).append(" ").append(PostgreSqlFieldsType.FK.getType()).append(" , \n");
            }

            sb.append("  PRIMARY KEY (").append(GlobalConstant.DEFAULT_PK).append(") \n");
            sb.append("); \n");
            sqls.add(sb.toString());
        }
        for (TableStructureConfig tableStructureConfig : tableStructureConfigs) {
            List<TableFieldConfig> tableFieldConfigs = tableStructureConfig.getTableFieldConfigs();
            //遍历当前表配置的 字段配置
            for (TableFieldConfig tableFieldConfig : tableFieldConfigs) {
                sqls.add("COMMENT ON COLUMN " + tableStructureConfig.getTableName() + "." + tableFieldConfig.getFieldName() + " IS '" + tableFieldConfig.getFieldComment() + "'");
            }

        }
        return sqls;
    }

    /**
     * 构建 判断表是否存在的sql
     * @param tableName
     * @param dbType
     * @return
     */
    private static String wrapperExistTableSql(String tableName, DbType dbType) {
        switch (dbType) {
            case ORACLE:
            case ORACLE_12C:
                return wrapperExistTableSqlForOracle(tableName);
            case SQL_SERVER:
                return wrapperExistTableSqlForSqlServer(tableName);
            case POSTGRE_SQL:
                return wrapperExistTableSqlForPostgreSql(tableName);
            case DM:
                return wrapperExistTableSqlForDm(tableName);
            case DB2:
                return wrapperExistTableSqlForDb2(tableName);
            case KINGBASE_ES:
                return wrapperExistTableSqlForKingBaseEs(tableName);
            case GAUSS:
                return wrapperExistTableSqlForGauss(tableName);
            default:
                return wrapperExistTableSqlForMysql(tableName);
        }
    }

    private static String wrapperExistTableSqlForMysql(String tableName) {
        return "select count(*) from information_schema.TABLES where TABLE_NAME = '" + tableName + "'";
    }

    private static String wrapperExistTableSqlForOracle(String tableName) {
        return "select count(*) from user_tables where table_name = '" + tableName + "'";
    }

    private static String wrapperExistTableSqlForSqlServer(String tableName) {
        return "select count(*) from sys.objects where object_id = OBJECT_ID('" + tableName + "')";
    }

    private static String wrapperExistTableSqlForPostgreSql(String tableName) {
        return "select count(*) from pg_catalog.pg_tables where tablename = '" + tableName + "'";
    }

    private static String wrapperExistTableSqlForDm(String tableName) {
        return "select count(*) from sysobjects where NAME = '" + tableName + "'";
    }

    private static String wrapperExistTableSqlForDb2(String tableName) {
        return "select count(*) from sysibm.systables where tablename = '" + tableName + "'";
    }

    private static String wrapperExistTableSqlForKingBaseEs(String tableName) {
        return "select count(*) from sys_tables where table_name = '" + tableName + "'";
    }

    private static String wrapperExistTableSqlForGauss(String tableName) {
        return "select count(*) from sys_tables where table_name = '" + tableName + "'";
    }

    public static Boolean testConnection(String url, String userName, String password) {
        Connection conn = null;
        try (SimpleDataSource ds = new SimpleDataSource(url, userName, password, com.alibaba.druid.util.JdbcUtils.getDriverClassName(url))) {
            ds.setLoginTimeout(5);
            conn = ds.getConnection();
        } catch (Exception e) {
            log.error("数据库连接失败！url: " + url, e);
            return false;
        } finally {
            DbUtil.close(conn);
        }
        return true;
    }

    public static String getDbType(DbType dbType, Integer typeCode) {
        switch (dbType) {
            case ORACLE:
            case ORACLE_12C:
            case DM:
            case DB2:
                return OracleFieldsType.getFieldType(typeCode).getType();
            case SQL_SERVER:
            case SQL_SERVER2005:
                return SqlServerFieldsType.getFieldType(typeCode).getType();
            case POSTGRE_SQL:
            case GAUSS:
                return PostgreSqlFieldsType.getFieldType(typeCode).getType();
            case KINGBASE_ES:
                return KingBaseFieldsType.getFieldType(typeCode).getType();
            default:
                return MySqlFieldsType.getFieldType(typeCode).getType();
        }
    }

    public static DbType getDbType(String datasourceId) {
        DataSource dataSource = getDataSource(datasourceId);
        if (dataSource != null) {
            Connection connection = null;
            try {
                connection = dataSource.getConnection();
                return JdbcUtils.getDbType(connection.getMetaData().getURL());
            } catch (Exception e) {
                log.error("获取数据库类型失败！", e);
            } finally {
                DbUtil.close(connection);
            }
        }
        return null;
    }
}
